/* NIXON Formatter
 * Copyright (C) 2009 NIXON Development Corporation.
 * All rights reserved.
 * http://members.shaw.ca/nixon.com
*/

package nixonftp;

import java.awt.Color;
import java.awt.Container;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import javax.swing.JOptionPane;

public class NXFormat {
	private static String[][] mExtensions = {
		{ "gif", "Graphics Interchange Format", "image/gif" },
		{ "jpg", "Joint Photographic Experts Group", "image/jpeg" },
		{ "png", "Portable Network Graphics", "image/png" },
		{ "svg", "Scalable Vector Graphics", "image/svg+xml" },

		{ "html", "Hypertext Markup Language", "text/html" },
		{ "htm", "Hypertext Markup", "text/html" },
		{ "xhtml", "Extensible Hypertext Markup Language", "application/xhtml+xml" },
		{ "php", "Hypertext Preprocessor", "application/x-php" },
		{ "rss", "Really Simple Syndication", "application/rss+xml" },
		{ "py", "Python", "application/x-python" },
		{ "asp", "Active Server Pages", "application/x-asp" },
		{ "cer", "Digital certificate", "application/x-x509-ca-cert" },
		{ "jsp", "Java Server Page", "application/jsp" },
		{ "aspx", "Microsoft ASP.NET", "text/html" },
		{ "do", "Java Servlet", "text/html" },
		{ "epub", "Open eBook", "application/epub+zip" },
		{ "vcf", "vCard", "text/x-vcard" },
		{ "jar", "Java Archive", "application/java-archive" },
		{ "cgi", "Common Gateway Interface", "application/cgi" },
		{ "torrent", "BitTorrent", "application/x-bittorrent" },
		{ "class", "Java Class", "application/java-vm" },
		
		{ "ttf", "TrueType", "font/ttf" },
		{ "otf", "OpenType", "font/otf" },
		{ "woff", "Web Open Font Format", "application/font-woff" },

		{ "css", "Cascading Style Sheets", "text/css" },
		{ "js", "JavaScript", "application/javascript" },
		{ "csv", "Comma-separated values", "text/csv" },
		{ "txt", "Plain text", "text/plain" },
		{ "xml", "Extensible Markup Language", "text/xml" },
		{ "wrl", "Virtual Reality Modeling Language", "model/vrml" },
		{ "pdf", "Portable Document Format", "application/pdf" },
		{ "ps", "Adobe PostScript", "application/postscript" },
		{ "psd", "Adobe Photoshop", "application/photoshop" },
		{ "ai", "Adobe Illustrator", "application/postscript" },
		{ "eps", "Encapsulated PostScript", "application/x-eps" },

		{ "tif", "Tag Image File Format", "image/tiff" },
		{ "fli", "Autodesk Animator", "video/fli" },
		{ "flc", "Autodesk Animator Pro", "video/flc" },
		{ "snd", "Sound Resource", "audio/basic" },
		{ "zip", "Data compression", "application/zip" },
		{ "gz", "GNU zip", "application/x-gzip" },
		{ "bz2", "bzip2", "application/x-bzip2" },
		{ "tar", "Tape archive", "application/tar" },
		{ "z", "Compress", "application/x-compress" },
		{ "mp3", "MPEG-2 Audio Layer III", "audio/mpeg" },
		{ "mid", "Musical Instrument Digital Interface", "audio/mid" },
		{ "mpg", "MPEG-1 Video", "video/mpeg" },
		{ "m4a", "MPEG-4 Audio", "audio/mp4" },
		{ "m4v", "MPEG-4 Video", "video/mp4" },
		{ "mp4", "ISO/IEC 14496-14:2003", "video/mp4" },
		{ "avi", "Audio Video Interleave", "video/x-msvideo" },
		{ "mov", "QuickTime Movie", "video/quicktime" },
		{ "ogg", "Ogg Vorbis", "audio/ogg" },
		{ "ogv", "Theora", "video/ogg" },
		{ "webm", "WebM", "video/webm" },
		{ "wmv", "Windows Media Video", "video/x-ms-wmv" },
		{ "asf", "Advanced Systems Format", "video/x-ms-asf" },
		{ "swf", "Shockwave Flash", "application/x-shockwave-flash" },
		{ "wma", "Windows Media Audio", "audio/x-ms-wma" },
		{ "flv", "Flash video", "video/x-flv" },
		{ "aac", "Advanced Audio Coding", "audio/x-aac" },

		{ "rtf", "Rich Text Format", "text/rtf" },
		{ "docx", "Office Open XML Document", "application/vnd.openxmlformats-officedocument.wordprocessingml.document" },
		{ "pptx", "Office Open XML Presentation", "application/vnd.openxmlformats-officedocument.presentationml.presentation" },
		{ "xlsx", "Office Open XML Workboox", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" },
		{ "doc", "Microsoft Word Document", "application/msword" },
		{ "xls", "Microsof Excel Spreadsheet", "application/vnd.ms-excel" },


	};

	class ExtensionInfo {
		String msgExt;
		String msgInfo;
		public ExtensionInfo(String e, String i) {
			msgExt = e;
			msgInfo = i;
		}
	}

	public static String fileSize(long bytes) {
		return fileSize(bytes, false);
	}

	public static String fileSize(long bytes, boolean precise) {
		String[] units = {"bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"};
		double value = 0;
		double newValue = 0;
		String append = "";
		if (precise) append = ".#";
		NumberFormat formatter = new DecimalFormat("0" + append);

		for (int x = units.length; x > 0; x--) {
			value = Math.pow(1024, x);
			if (bytes > value) {
				newValue = bytes / value;
				return formatter.format(newValue) + " " + units[x];
			}
		}
		return String.valueOf(bytes) + " " + units[0];
	}

	public static long getSizeFromRemotePath(String remoteFile, HashMap index) {
		String[] parts = getNameFromPath(remoteFile); //get parent directory, filename only
		String fileName = parts[1];
		String pathName = parts[0];
		NXObjectIndex oi = (NXObjectIndex) index.get(pathName);
		NXObjectIndex obj = (NXObjectIndex) oi.objects.get(fileName);
		return obj.size;
	}

	public static boolean isImage(String fileName) {
		String ext = getExtension(fileName).toLowerCase();
		String[] exts = {"gif", "jpg", "jpeg", "png", "bmp", "wbmp", "ico"};
		for (int x = 0; x < exts.length; x++) {
			if (ext.equals(exts[x])) {
				return true;
			}
		}
		return false;
	}

	public static String parseDate(Date d) {
		Calendar current = Calendar.getInstance();
		Calendar c = Calendar.getInstance();
		c.setTime(d);
		long currMS = current.getTimeInMillis();
		long MS = c.getTimeInMillis();
		long diff = currMS - MS;
		double secDiff = (double) diff / 1000;
		double years = secDiff / 31557600;

		if (years <= 1) {
			double dayDiff = years * 365; //assuming no time travel to future
			NumberFormat formatter = new DecimalFormat("00");
			String time = formatter.format(c.get(Calendar.HOUR)) + ":" + formatter.format(c.get(Calendar.MINUTE));

			if (dayDiff > 30) { //month
				return estDate(dayDiff / 30, "month");
			} else if (dayDiff >= 7) { //week
				return estDate(dayDiff / 7, "week");
			} else if (dayDiff > 1) { //day
				return estDate(dayDiff, "day") + " at " + time;
			} else { //today
				return "Today at " + time;
			}
		} else {
			return estDate(years, "year");
		}
	}

	public static String parseTime(long secs) {
		if (secs == 0) return "";
		String units = null; long cmp; long result; String s;
		int unit; String strResult;

		for (int x = 4; x > 0; x--) {
			if (x == 4) cmp = 86400;
			else if (x == 1) cmp = 0;
			else cmp = (long) Math.pow(60, x - 1);
			if (secs >= cmp) {
				if (x == 1) { units = "sec"; }
				else if (x == 2) { units = "min"; }
				else if (x == 3) { units = "hr"; }
				else if (x == 4) { units = "day"; }
				if (cmp != 0) {
					result = secs / cmp;
				} else {
					result = secs;
				}
				s = (result != 1) ? "s" : "";
				strResult = result + " " + units + s;

				if (cmp != 0) {
					return strResult + " " + parseTime(secs - result * cmp);
				} else {
					return strResult;
				}
			}
		}

		return "";
	}

	public static int getEta(long size, long transferred, int bps) {
		int eta = (bps != 0) ? (int) ((size - transferred) / bps) : 0;
		return eta;
	}

	public static String eta(int eta) {
		String strEta = parseTime(eta);
		if (!strEta.equals("")) strEta = " (" + strEta + ")";
		return strEta;
	}
	
	private static String estDate(double units, String unit) {
		int convert = (int) Math.round(units);
		String s = "";
		if (convert > 1) s = "s";
		return String.valueOf(convert) + " " + unit + s + " ago";
	}

	public static String getNameFromPath(String path, boolean reverse) {
		int pos, pos1;
		pos = reverseFind(path, "/");
		if (pos == -1) pos = reverseFind(path, "\\");
		if (pos != -1) {
			if (reverse) return path.substring(0, pos);
			else return path.substring(pos + 1);
		} else {
			return path;
		}
	}

	public static String[] getNameFromPath(String path) {
		int pos, pos1;
		String[] parts = new String[2];
		String slash = "/";
		pos = reverseFind(path, slash);
		if (pos == -1) {
			slash = "\\";
			pos = reverseFind(path, slash);
		}
		if (pos != -1) {
			if (pos > 0) {
				parts[0] = path.substring(0, pos);
				parts[1] = path.substring(pos + 1);
			} else {
				parts[0] = slash;
				parts[1] = path.substring(1);
			}
		} else {
			parts[0] = path;
		}
		return parts;
	}

	public static String getExtension(String s) {
		int pos = reverseFind(s, ".");
		if (pos == -1) {
			return "";
		} else {
			return s.substring(pos + 1);
		}
	}

	public static String[] getTypeFromExtension(String s) {
		String[] data;
		for (int x = 0; x < mExtensions.length; x++) {
			data = mExtensions[x];
			if (data[0].equals(s)) {
				return new String[] { data[1], data[2] };
			}
		}
		return new String[] { "Unknown", "" };
	}

	private static int reverseFind(String s, String match) {
		int pos = -1;
		int lastPos = -1;
		do {
			pos = s.indexOf(match, pos + 1);
			if (pos != -1) lastPos = pos;
		} while (pos != -1);
		return lastPos;
	}

	public static Color invertColor(Color color) {
		int r = color.getRed();
		int g = color.getGreen();
		int b = color.getBlue();
		if (r == 127 && g == 127 && b == 127) {
			return new Color(0,0,0);
		} else {
			return new Color(255 - r, 255 - g, 255 - b);
		}
	}

	public static int alertBox(Container c, String message, String detail, int optionType, int alertType, Object[] options, int defaultButton) {
		int n = JOptionPane.showOptionDialog(c,
				"<html><table width='360'><tr><td><strong>" + message + "</strong>"
				+ "</td></tr><tr><td>" + detail + "</td></tr></table></html>",
				null,
				optionType,
				alertType,
				null,
				options,
				options[defaultButton]);
		return n;
	}
}
